now = now or 0	--当前时间
d = d or 0		--真实时间的偏移值

local Msg = require("core.Msg")
local Monitor = require("core.Monitor")
local Log = require("common.Log")

last_exe_time = last_exe_time or {}

if _G.is_world then
    local Human = require("core.Human")
    local TeamLogic = require("team.TeamLogic")
    local FamilyLogicFW = require("family.FamilyLogicFW")
    local FamilyManager = require("family.FamilyManager")
    local ActivityLogicW = require("activity.ActivityLogicW")
    local CopyTeamSignW = require("copy.CopyTeamSignW")
    local AdminBroadcast = require("admin.AdminBroadcast")
    local TaskGroupW = require("task.TaskGroupW")
    local OfflinePkLogicW = require("offlinepk.OfflinePkLogicW")
    local Config = require("Config")
    local ArmyRiotLogicW = require("activity.armyRiot.ArmyRiotLogicW")
    local TencentPayLogic = require("tencentApi.PayLogic")
    local MiddleLogic = require("middle.MiddleLogic")
    local MiddleCopySign = require("middle.MiddleCopySign")
    local MiddleFamilySign = require("middle.MiddleFamilySign")
    local ServerCommonFW = require("serverCommon.ServerCommonFW")
    local OperateActFW = require("activity.OperateActFW")
    local ComplexSrvActFW = require("activity.ComplexSrvActFW")
    local DateActFW = require("activity.DateActFW")
    local RankHandlerW = require("rank.HandlerW")
    local ShopHandlerW = require("shop.HandlerW")
    local QPoint = require("activity.operate.QPoint")
    local OperateActLogicW = require("activity.operate.OperateActLogicW")
    local ComplexSrvActLogicW = require("activity.complex.ComplexSrvActLogicW")
    local DateActLogicW = require("activity.date.DateActLogicW")
    
    
    IS_SERVER_DOWN = IS_SERVER_DOWN or false 
    register_timer = {
        save_db = 1000,
        onZhengDian = 60000,      --整点逻辑，放在world里触发，然后通知logic触发。 保证world里整点逻辑在先
        onSaveRank = 300000,      --每隔五分钟保存下排行榜数据
        checkTeamMember = 5000,
        onSecond = 1000,            --每秒逻辑
        signTeam = 1000,            -- 匹配组队副本
        activitycheck = 5000,      --每分钟活动开放检测
        adminBroadcast = 10000,     --10s warning!! keep it!! 这个里面有gc debug时不要随便把这个timer干掉
        clearTransaction = 60000,   --
        monitor = 60000,
        humanOfflineCheck = 10000,
        middleHeartbeat = 120000, --2min
        on1Min = 60000,
        middleFamilyWar = 5000,
        middleFamilyWarMinute = 60000,
    }

	function on1Min()
		Human.human1Min()
	end

    function onSaveRank(closeServer)
        if IS_SERVER_DOWN and not closeServer then
          return
        end
        if closeServer then
          IS_SERVER_DOWN = true
        end

        RankHandlerW.saveRank()
        ShopHandlerW.updateCnt()
    end

    function save_db()    
        Human.save_db()        
    end

    function onZhengDian(during, isGM)
        if not isGM and (lastUpDateTime and (now - lastUpDateTime) < 180000 or 120000 < now % (1000 * 60 * 60)) then
            return
        end
        local hour
        if isGM then
            hour = isGM
        else                   
            lastUpDateTime = now
            hour = os.date("%H", os.time()) + 0
        end
        
        ServerCommonFW.HAD_OPEN_DAY = nil
        ServerCommonFW.HAD_COMPLEXSRV_DAY = nil
        
        MiddleLogic.checkNeedOpen()  
        
        -- 整点的时候刷新逻辑用的内存较多 这里gc一把
        _G.collectgarbage("step", 100000)

        
        if hour == 4 then
            --    FamilyLogicFW.on4Clock()
        end

        if hour == 23 then
            OperateActLogicW.onChongzhiCalc()
            ComplexSrvActLogicW.onChongzhiCalc()
        end

        if hour == 0 then
            FamilyLogicFW.extend()
            FamilyManager.updateDaily(true)
            TaskGroupW.refreshTaskGroupPool()
            OperateActFW.onInitTodayAct()
            OperateActFW.onActCheck()
            ComplexSrvActFW.onInitTodayAct()
            ComplexSrvActFW.onActCheck()
            DateActFW.onInitTodayAct()
            DateActFW.onActCheck()
            OperateActLogicW.clearRecord()   
            DateActLogicW.onHolidayGiftReset()
            ComplexSrvActLogicW.onHolidayGiftReset()
            DateActLogicW.clearRecord()
        end       

        --通知逻辑线程
        local msgRet = Msg.wl.WL_ZHENG_DIAN
        msgRet.hour = hour
        for i = 0, 3 do
            Msg.send2logic_id(msgRet, i)
        end
        msgRet = Msg.gc.GC_ZHENG_DIAN
        msgRet.hour = hour
        Msg.sendAll(msgRet)
        RankHandlerW.writeLog()
        if hour == 21 and not Config.IS_MIDDLE then
            OfflinePkLogicW.onNightReward()      
            QPoint.checkEnough()      
        end
        if hour == 22 and not Config.IS_MIDDLE then
          QPoint.setReward()
          OperateActLogicW.checkLvCanGet()
          OperateActLogicW.checkPataCanGet()
        end
        -- 整点的时候刷新逻辑用的内存较多 这里gc一把
        _G.collectgarbage("step", 100000)
    end
    function checkTeamMember()
        TeamLogic.checkTeamMember()
    end

    function onSecond()
        FamilyLogicFW.extend()
    end

    function signTeam()
        if Config.IS_MIDDLE then
          MiddleCopySign.onTimer1Second()
        else
          CopyTeamSignW.onTimer1Second()
        end
    end

    function activitycheck()
        ActivityLogicW.onActCheck()
    end
    
    function adminBroadcast()
        AdminBroadcast.OnCheckBroadcast()
        ArmyRiotLogicW.sendRiotRank()
        _G.collectgarbage("step", 100000)
    end
    
    local counter = 0
    function clearTransaction()
        TencentPayLogic.Update()
        counter = counter + 1
        if counter == 5 then
          TencentPayLogic.checkIsLogin()
          counter = 0
        end
    end
    
    function monitor()    
      Log.write(Log.LOGID_MONITOR, "world:", math.floor(_G.collectgarbage("count")).."KB")
      Monitor.output()
    end
    
    function humanOfflineCheck()
      Human.humanOfflineCheck()
    end
    
    function middleHeartbeat()
      MiddleLogic.heartBeat()
    end
    
    function middleFamilyWar()
      MiddleFamilySign.onTimer5Second()
    end
    
    function middleFamilyWarMinute()
      MiddleFamilySign.onTimerMinute()
    end
else
    local Obj = require("core.Obj")
    local ObjHuman = require("core.ObjHuman")
    local ObjMonster = require("core.ObjMonster")
    local SceneEvent = require("core.SceneEvent")
    local MonsterAi  = require("monster.MonsterAi")
    local Skill = require("skill.Skill")
    local Buffer = require("buffer.Buffer")
    local ObjAoe = require("core.ObjAoe")
    local ObjTrap = require("core.ObjTrap")
    local ObjMagic =require("core.ObjMagic")
    local ObjItem  = require("core.ObjItem")
    local ObjCollect = require("core.ObjCollect")
    local Copy = require("copy.CopyL")
    local TaskLogic = require("task.TaskLogic")
    local FcmLogic = require("fcm.FcmLogic")
    local PetAi = require("pet.PetAi")
    local PetLogic = require("pet.PetLogic")
    local WorldBossLogicL = require("worldboss.WorldBossLogicL")
    local JZWar = require("copy.JZWar")
    local FamilyWar = require("copy.FamilyWar")
    local CCJJWar = require("copy.CCJJWar")
    local DHFight = require("copy.DHFight")
    local OperateActLogicL = require("activity.operate.OperateActLogicL")    
    local TitleLogic = require("title.TitleLogic")
    register_timer = {
        walk = 400,
        scene_ai = 444,
        scene_ai_err = 4444,
        aoe = 250,
        trap = 700,
        buf = 250,
        check_obj_collect_reborn = 1000,
        humanHpRecover = 20000,  --hp恢复，坐骑限时判定
        humanMiningEnergyRecover = 300000,--5min
        humanOfflineCheck = 10000,
        time_enter_scene_list = 444,
        monster_ai = 600,
        skill = 150,
        fcmCheck = 60000,
        check_obj_item_expire = 3000,
        human1second = 1000,
        copy = 10000,
        pet_ai  = 400,
        worldbossSceneData = 1000,
        objItemBloodAi = 1000,
        jzWarComboKill = 500,
        monitor = 60000,
        titleCheck = 5000,
    }
    function walk(during)
        
        Obj.walk(during)
    end
    function scene_ai()
        for k in pairs(Obj.scenes) do
            if not SceneEvent.has_err[k] then
                SceneEvent.has_err[k] = true
                SceneEvent.ai(k)
                SceneEvent.has_err[k] = nil
            end
        end
    end

    function scene_ai_err()
        for k in pairs(Obj.scenes) do
            if SceneEvent.has_err[k] then
                SceneEvent.ai(k)
                SceneEvent.has_err[k] = nil
            end
        end
    end

    function buf(during)
        Buffer.onTimer(during)
    end


    function humanHpRecover()
        ObjHuman.humanHpRecover()
    end

    function humanMiningEnergyRecover()
        --	ObjHuman.humanMiningEnergyRecover()
    end

    function human1second()
        ObjHuman.human1second()
        Copy.onTimerOneSec()
    end

    function humanOfflineCheck()
        ObjHuman.humanOfflineCheck()
    end

    function time_enter_scene_list()
        ObjMonster.time_enter_scene_list(now)
    end

    function monster_ai()
        MonsterAi.ai()
    end

    function pet_ai()
        PetAi.time()
    end

    function skill(during)
        Skill.onTimer(during)
    end

    function aoe(during)
        ObjAoe.onTimer(during)
        ObjMagic.onTimer(during)
    end
    
    function trap(during)
        ObjTrap.onTimer(during)
    end

    function check_obj_item_expire()
        ObjItem.checkExpire()
    end

    function check_obj_collect_reborn()
        ObjCollect.checkReborn()
    end

    function copy()
        Copy.onTimerTenSec()

        _G.collectgarbage("step", 100000)
    end



    function onZhengDian(hour)
        -- 整点的时候刷新逻辑用的内存较多 这里gc一把
        _G.collectgarbage("step", 100000)
        if hour == 23 then
            TaskLogic.onBeforeMidNight()
        end

        if hour == 0 then  
            for _,human in pairs(ObjHuman.onlineUuid) do
                ObjHuman.humanOnlineCrossDay(human)
            end
            TaskLogic.onMidNight()
            OperateActLogicL.clearRankName()
        end

        -- 整点的时候刷新逻辑用的内存较多 这里gc一把
        _G.collectgarbage("step", 100000)
    end


    function fcmCheck()
        FcmLogic.checkFcm()
    end

    function worldbossSceneData()
        WorldBossLogicL.onCtlBossData()
    end
    
    function objItemBloodAi()    
        ObjItem.objItemBloodAi()
    end
    
    function jzWarComboKill()
        JZWar.onCheckComboKill() 
        FamilyWar.onCheckComboKill()
        CCJJWar.onCheckComboKill()
        DHFight.onCheckComboKill()
    end
    
    function titleCheck()
        TitleLogic.checkExpire()
    end
    
    function monitor()
      local sum_scene = 0
      for _ in pairs(Obj.scenes) do
          sum_scene = sum_scene + 1
      end
      local sum_obj = 0
      local sum_monster = 0
      local sum_human = 0
      local sum_pet = 0
      for _, v in pairs(Obj.objs) do
        sum_obj = sum_obj + 1
        if v.obj_type == Obj.TYPE_HUMAN then
          sum_human = sum_human + 1
        elseif v.obj_type == Obj.TYPE_PET then
          sum_pet = sum_pet + 1
        elseif v.monster_id then
          sum_monster = sum_monster + 1
        end
      end
      Log.write(Log.LOGID_MONITOR, "logic:".._G.logic_id, math.floor(_G.collectgarbage("count")).."KB", sum_scene, sum_obj, sum_monster, sum_human, sum_pet)
      Monitor.output()
end
end


function onGetDeviationTime(key)
    if last_exe_time[key] and register_timer[key] then
        local alg = now - last_exe_time[key]
        if alg then
            return alg
        else
            local nDeviaitionTime = register_timer[key] -alg
            print(nDeviaitionTime)
            return nDeviaitionTime
        end
    end
    return 0
end

function handlerTime(msec)

    now = msec + d
    if not register_timer[last_exe_func] then
        last_exe_func = nil
    end
    local tmp = last_exe_func
    while true do
        local k, v = next(register_timer, last_exe_func)
        if not k then
            k, v = next(register_timer)
        end
        if not k then
            return
        end
       
        last_exe_func = k

        local last_time = last_exe_time[k]
        if last_time then
            if last_time + v <= now then
                last_exe_time[k] = now
                Monitor.handleTimer(_ENV[k], now - last_time, k)   
                if not _G.is_world and k ~= "skill" then
                  local last_time = last_exe_time["skill"] or 0
                  if last_time + 150 <= now then
                      last_exe_time["skill"] = now
                      Monitor.handleTimer(_ENV["skill"], now - last_time, "skill")
                  end
                end                
                break
            end
        else
            last_exe_time[k] = now
            break
        end
        if k == tmp then
            return
        end
    end
end

